home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / pvm34b3.zip / pvm34b3 / pvm3 / xdr / xdr.c < prev    next >
C/C++ Source or Header  |  1997-07-22  |  11KB  |  588 lines

  1. /* @(#)xdr.c    2.1 88/07/29 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  *
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  *
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  *
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  *
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  *
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30.  
  31.  
  32. #if !defined(lint) && defined(SCCSIDS)
  33. static char sccsid[] = "@(#)xdr.c 1.35 87/08/12";
  34. #endif
  35.  
  36. /*
  37.  * xdr.c, Generic XDR routines implementation.
  38.  *
  39.  * Copyright (C) 1986, Sun Microsystems, Inc.
  40.  *
  41.  * These are the "generic" xdr routines used to serialize and de-serialize
  42.  * most common data items.  See xdr.h for more info on the interface to
  43.  * xdr.
  44.  */
  45.  
  46. #include <stdio.h>
  47. char *malloc();
  48.  
  49. #include "..\xdr\types.h"
  50. #include "..\xdr\xdr.h"
  51.  
  52. /*
  53.  * constants specific to the xdr "protocol"
  54.  */
  55. #define XDR_FALSE    ((long) 0)
  56. #define XDR_TRUE    ((long) 1)
  57. #define LASTUNSIGNED    ((u_int) 0-1)
  58.  
  59. /*
  60.  * for unit alignment
  61.  */
  62. static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 };
  63.  
  64. /*
  65.  * Free a data structure using XDR
  66.  * Not a filter, but a convenient utility nonetheless
  67.  */
  68. void
  69. xdr_free(proc, objp)
  70.     xdrproc_t proc;
  71.     char *objp;
  72. {
  73.     XDR x;
  74.  
  75.     x.x_op = XDR_FREE;
  76.     (*proc)(&x, objp);
  77. }
  78.  
  79. /*
  80.  * XDR nothing
  81.  */
  82. bool_t
  83. xdr_void(/* xdrs, addr */)
  84.     /* XDR *xdrs; */
  85.     /* caddr_t addr; */
  86. {
  87.  
  88.     return (TRUE);
  89. }
  90.  
  91. /*
  92.  * XDR integers
  93.  */
  94. bool_t
  95. xdr_int(xdrs, ip)
  96.     XDR *xdrs;
  97.     int *ip;
  98. {
  99.  
  100. #ifdef lint
  101.     (void) (xdr_short(xdrs, (short *)ip));
  102.     return (xdr_long(xdrs, (long *)ip));
  103. #else
  104.     if (sizeof (int) == sizeof (long)) {
  105.         return (xdr_long(xdrs, (long *)ip));
  106.     } else {
  107.         return (xdr_short(xdrs, (short *)ip));
  108.     }
  109. #endif
  110. }
  111.  
  112. /*
  113.  * XDR unsigned integers
  114.  */
  115. bool_t
  116. xdr_u_int(xdrs, up)
  117.     XDR *xdrs;
  118.     u_int *up;
  119. {
  120.  
  121. #ifdef lint
  122.     (void) (xdr_short(xdrs, (short *)up));
  123.     return (xdr_u_long(xdrs, (u_long *)up));
  124. #else
  125.     if (sizeof (u_int) == sizeof (u_long)) {
  126.         return (xdr_u_long(xdrs, (u_long *)up));
  127.     } else {
  128.         return (xdr_short(xdrs, (short *)up));
  129.     }
  130. #endif
  131. }
  132.  
  133. /*
  134.  * XDR long integers
  135.  * same as xdr_u_long - open coded to save a proc call!
  136.  */
  137. bool_t
  138. xdr_long(xdrs, lp)
  139.     register XDR *xdrs;
  140.     long *lp;
  141. {
  142.  
  143.     if (xdrs->x_op == XDR_ENCODE)
  144.         return (XDR_PUTLONG(xdrs, lp));
  145.  
  146.     if (xdrs->x_op == XDR_DECODE)
  147.         return (XDR_GETLONG(xdrs, lp));
  148.  
  149.     if (xdrs->x_op == XDR_FREE)
  150.         return (TRUE);
  151.  
  152.     return (FALSE);
  153. }
  154.  
  155. /*
  156.  * XDR unsigned long integers
  157.  * same as xdr_long - open coded to save a proc call!
  158.  */
  159. bool_t
  160. xdr_u_long(xdrs, ulp)
  161.     register XDR *xdrs;
  162.     u_long *ulp;
  163. {
  164.  
  165.     if (xdrs->x_op == XDR_DECODE)
  166.         return (XDR_GETLONG(xdrs, (long *)ulp));
  167.     if (xdrs->x_op == XDR_ENCODE)
  168.         return (XDR_PUTLONG(xdrs, (long *)ulp));
  169.     if (xdrs->x_op == XDR_FREE)
  170.         return (TRUE);
  171.     return (FALSE);
  172. }
  173.  
  174. /*
  175.  * XDR short integers
  176.  */
  177. bool_t
  178. xdr_short(xdrs, sp)
  179.     register XDR *xdrs;
  180.     short *sp;
  181. {
  182.     long l;
  183.  
  184.     switch (xdrs->x_op) {
  185.  
  186.     case XDR_ENCODE:
  187.         l = (long) *sp;
  188.         return (XDR_PUTLONG(xdrs, &l));
  189.  
  190.     case XDR_DECODE:
  191.         if (!XDR_GETLONG(xdrs, &l)) {
  192.             return (FALSE);
  193.         }
  194.         *sp = (short) l;
  195.         return (TRUE);
  196.  
  197.     case XDR_FREE:
  198.         return (TRUE);
  199.     }
  200.     return (FALSE);
  201. }
  202.  
  203. /*
  204.  * XDR unsigned short integers
  205.  */
  206. bool_t
  207. xdr_u_short(xdrs, usp)
  208.     register XDR *xdrs;
  209.     u_short *usp;
  210. {
  211.     u_long l;
  212.  
  213.     switch (xdrs->x_op) {
  214.  
  215.     case XDR_ENCODE:
  216.         l = (u_long) *usp;
  217.         return (XDR_PUTLONG(xdrs, &l));
  218.  
  219.     case XDR_DECODE:
  220.         if (!XDR_GETLONG(xdrs, &l)) {
  221.             return (FALSE);
  222.         }
  223.         *usp = (u_short) l;
  224.         return (TRUE);
  225.  
  226.     case XDR_FREE:
  227.         return (TRUE);
  228.     }
  229.     return (FALSE);
  230. }
  231.  
  232.  
  233. /*
  234.  * XDR a char
  235.  */
  236. bool_t
  237. xdr_char(xdrs, cp)
  238.     XDR *xdrs;
  239.     char *cp;
  240. {
  241.     int i;
  242.  
  243.     i = (*cp);
  244.     if (!xdr_int(xdrs, &i)) {
  245.         return (FALSE);
  246.     }
  247.     *cp = i;
  248.     return (TRUE);
  249. }
  250.  
  251. /*
  252.  * XDR an unsigned char
  253.  */
  254. bool_t
  255. xdr_u_char(xdrs, cp)
  256.     XDR *xdrs;
  257.     char *cp;
  258. {
  259.     u_int u;
  260.  
  261.     u = (*cp);
  262.     if (!xdr_u_int(xdrs, &u)) {
  263.         return (FALSE);
  264.     }
  265.     *cp = u;
  266.     return (TRUE);
  267. }
  268.  
  269. /*
  270.  * XDR booleans
  271.  */
  272. bool_t
  273. xdr_bool(xdrs, bp)
  274.     register XDR *xdrs;
  275.     bool_t *bp;
  276. {
  277.     long lb;
  278.  
  279.     switch (xdrs->x_op) {
  280.  
  281.     case XDR_ENCODE:
  282.         lb = *bp ? XDR_TRUE : XDR_FALSE;
  283.         return (XDR_PUTLONG(xdrs, &lb));
  284.  
  285.     case XDR_DECODE:
  286.         if (!XDR_GETLONG(xdrs, &lb)) {
  287.             return (FALSE);
  288.         }
  289.         *bp = (lb == XDR_FALSE) ? FALSE : TRUE;
  290.         return (TRUE);
  291.  
  292.     case XDR_FREE:
  293.         return (TRUE);
  294.     }
  295.     return (FALSE);
  296. }
  297.  
  298. /*
  299.  * XDR enumerations
  300.  */
  301. bool_t
  302. xdr_enum(xdrs, ep)
  303.     XDR *xdrs;
  304.     enum_t *ep;
  305. {
  306. #ifndef lint
  307.     enum sizecheck { SIZEVAL };    /* used to find the size of an enum */
  308.  
  309.     /*
  310.      * enums are treated as ints
  311.      */
  312.     if (sizeof (enum sizecheck) == sizeof (long)) {
  313.         return (xdr_long(xdrs, (long *)ep));
  314.     } else if (sizeof (enum sizecheck) == sizeof (short)) {
  315.         return (xdr_short(xdrs, (short *)ep));
  316.     } else {
  317.         return (FALSE);
  318.     }
  319. #else
  320.     (void) (xdr_short(xdrs, (short *)ep));
  321.     return (xdr_long(xdrs, (long *)ep));
  322. #endif
  323. }
  324.  
  325. /*
  326.  * XDR opaque data
  327.  * Allows the specification of a fixed size sequence of opaque bytes.
  328.  * cp points to the opaque object and cnt gives the byte length.
  329.  */
  330. bool_t
  331. xdr_opaque(xdrs, cp, cnt)
  332.     register XDR *xdrs;
  333.     caddr_t cp;
  334.     register u_int cnt;
  335. {
  336.     register u_int rndup;
  337.     static crud[BYTES_PER_XDR_UNIT];
  338.  
  339.     /*
  340.      * if no data we are done
  341.      */
  342.     if (cnt == 0)
  343.         return (TRUE);
  344.  
  345.     /*
  346.      * round byte count to full xdr units
  347.      */
  348.     rndup = cnt % BYTES_PER_XDR_UNIT;
  349.     if (rndup > 0)
  350.         rndup = BYTES_PER_XDR_UNIT - rndup;
  351.  
  352.     if (xdrs->x_op == XDR_DECODE) {
  353.         if (!XDR_GETBYTES(xdrs, cp, cnt)) {
  354.             return (FALSE);
  355.         }
  356.         if (rndup == 0)
  357.             return (TRUE);
  358.         return (XDR_GETBYTES(xdrs, crud, rndup));
  359.     }
  360.  
  361.     if (xdrs->x_op == XDR_ENCODE) {
  362.         if (!XDR_PUTBYTES(xdrs, cp, cnt)) {
  363.             return (FALSE);
  364.         }
  365.         if (rndup == 0)
  366.             return (TRUE);
  367.         return (XDR_PUTBYTES(xdrs, xdr_zero, rndup));
  368.     }
  369.  
  370.     if (xdrs->x_op == XDR_FREE) {
  371.         return (TRUE);
  372.     }
  373.  
  374.     return (FALSE);
  375. }
  376.  
  377. /*
  378.  * XDR counted bytes
  379.  * *cpp is a pointer to the bytes, *sizep is the count.
  380.  * If *cpp is NULL maxsize bytes are allocated
  381.  */
  382. bool_t
  383. xdr_bytes(xdrs, cpp, sizep, maxsize)
  384.     register XDR *xdrs;
  385.     char **cpp;
  386.     register u_int *sizep;
  387.     u_int maxsize;
  388. {
  389.     register char *sp = *cpp;  /* sp is the actual string pointer */
  390.     register u_int nodesize;
  391.  
  392.     /*
  393.      * first deal with the length since xdr bytes are counted
  394.      */
  395.     if (! xdr_u_int(xdrs, sizep)) {
  396.         return (FALSE);
  397.     }
  398.     nodesize = *sizep;
  399.     if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) {
  400.         return (FALSE);
  401.     }
  402.  
  403.     /*
  404.      * now deal with the actual bytes
  405.      */
  406.     switch (xdrs->x_op) {
  407.  
  408.     case XDR_DECODE:
  409.         if (nodesize == 0) {
  410.             return (TRUE);
  411.         }
  412.         if (sp == NULL) {
  413.             *cpp = sp = (char *)mem_alloc(nodesize);
  414.         }
  415.         if (sp == NULL) {
  416. #ifdef WIN32
  417.             nt_rpc_report("xdr_bytes: out of memory\n");
  418. #else
  419.             (void) fprintf(stderr, "xdr_bytes: out of memory\n");
  420. #endif
  421.             return (FALSE);
  422.         }
  423.         /* fall into ... */
  424.  
  425.     case XDR_ENCODE:
  426.         return (xdr_opaque(xdrs, sp, nodesize));
  427.  
  428.     case XDR_FREE:
  429.         if (sp != NULL) {
  430.             mem_free(sp, nodesize);
  431.             *cpp = NULL;
  432.         }
  433.         return (TRUE);
  434.     }
  435.     return (FALSE);
  436. }
  437.  
  438. /*
  439.  * Implemented here due to commonality of the object.
  440.  */
  441. bool_t
  442. xdr_netobj(xdrs, np)
  443.     XDR *xdrs;
  444.     struct netobj *np;
  445. {
  446.  
  447.     return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ));
  448. }
  449.  
  450. /*
  451.  * XDR a descriminated union
  452.  * Support routine for discriminated unions.
  453.  * You create an array of xdrdiscrim structures, terminated with
  454.  * an entry with a null procedure pointer.  The routine gets
  455.  * the discriminant value and then searches the array of xdrdiscrims
  456.  * looking for that value.  It calls the procedure given in the xdrdiscrim
  457.  * to handle the discriminant.  If there is no specific routine a default
  458.  * routine may be called.
  459.  * If there is no specific or default routine an error is returned.
  460.  */
  461. bool_t
  462. xdr_union(xdrs, dscmp, unp, choices, dfault)
  463.     register XDR *xdrs;
  464.     enum_t *dscmp;        /* enum to decide which arm to work on */
  465.     char *unp;        /* the union itself */
  466.     struct xdr_discrim *choices;    /* [value, xdr proc] for each arm */
  467.     xdrproc_t dfault;    /* default xdr routine */
  468. {
  469.     register enum_t dscm;
  470.  
  471.     /*
  472.      * we deal with the discriminator;  it's an enum
  473.      */
  474.     if (! xdr_enum(xdrs, dscmp)) {
  475.         return (FALSE);
  476.     }
  477.     dscm = *dscmp;
  478.  
  479.     /*
  480.      * search choices for a value that matches the discriminator.
  481.      * if we find one, execute the xdr routine for that value.
  482.      */
  483.     for (; choices->proc != NULL_xdrproc_t; choices++) {
  484.         if (choices->value == dscm)
  485.             return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED));
  486.     }
  487.  
  488.     /*
  489.      * no match - execute the default xdr routine if there is one
  490.      */
  491.     return ((dfault == NULL_xdrproc_t) ? FALSE :
  492.         (*dfault)(xdrs, unp, LASTUNSIGNED));
  493. }
  494.  
  495.  
  496. /*
  497.  * Non-portable xdr primitives.
  498.  * Care should be taken when moving these routines to new architectures.
  499.  */
  500.  
  501.  
  502. /*
  503.  * XDR null terminated ASCII strings
  504.  * xdr_string deals with "C strings" - arrays of bytes that are
  505.  * terminated by a NULL character.  The parameter cpp references a
  506.  * pointer to storage; If the pointer is null, then the necessary
  507.  * storage is allocated.  The last parameter is the max allowed length
  508.  * of the string as specified by a protocol.
  509.  */
  510. bool_t
  511. xdr_string(xdrs, cpp, maxsize)
  512.     register XDR *xdrs;
  513.     char **cpp;
  514.     u_int maxsize;
  515. {
  516.     register char *sp = *cpp;  /* sp is the actual string pointer */
  517.     u_int size;
  518.     u_int nodesize;
  519.  
  520.     /*
  521.      * first deal with the length since xdr strings are counted-strings
  522.      */
  523.     switch (xdrs->x_op) {
  524.     case XDR_FREE:
  525.         if (sp == NULL) {
  526.             return(TRUE);    /* already free */
  527.         }
  528.         /* fall through... */
  529.     case XDR_ENCODE:
  530.         size = strlen(sp);
  531.         break;
  532.     }
  533.     if (! xdr_u_int(xdrs, &size)) {
  534.         return (FALSE);
  535.     }
  536.     if (size > maxsize) {
  537.         return (FALSE);
  538.     }
  539.     nodesize = size + 1;
  540.  
  541.     /*
  542.      * now deal with the actual bytes
  543.      */
  544.     switch (xdrs->x_op) {
  545.  
  546.     case XDR_DECODE:
  547.         if (nodesize == 0) {
  548.             return (TRUE);
  549.         }
  550.         if (sp == NULL)
  551.             *cpp = sp = (char *)mem_alloc(nodesize);
  552.         if (sp == NULL) {
  553. #ifdef WIN32
  554.             nt_rpc_report("xdr_string: out of memory\n");
  555. #else
  556.             (void) fprintf(stderr, "xdr_string: out of memory\n");
  557. #endif
  558.             return (FALSE);
  559.         }
  560.         sp[size] = 0;
  561.         /* fall into ... */
  562.  
  563.     case XDR_ENCODE:
  564.         return (xdr_opaque(xdrs, sp, size));
  565.  
  566.     case XDR_FREE:
  567.         mem_free(sp, nodesize);
  568.         *cpp = NULL;
  569.         return (TRUE);
  570.     }
  571.     return (FALSE);
  572. }
  573.  
  574. /*
  575.  * Wrapper for xdr_string that can be called directly from
  576.  * routines like clnt_call
  577.  */
  578. bool_t
  579. xdr_wrapstring(xdrs, cpp)
  580.     XDR *xdrs;
  581.     char **cpp;
  582. {
  583.     if (xdr_string(xdrs, cpp, LASTUNSIGNED)) {
  584.         return (TRUE);
  585.     }
  586.     return (FALSE);
  587. }
  588.